package poc

import (
	"regexp"
	"strconv"
	"strings"
)

// Matcher 匹配器接口
type Matcher interface {
	Match(response *Response, variables map[string]string) bool
}

// ExpressionMatcher 表达式匹配器
type ExpressionMatcher struct {
	expression string
}

// NewExpressionMatcher 创建表达式匹配器
func NewExpressionMatcher(expression string) *ExpressionMatcher {
	return &ExpressionMatcher{expression: expression}
}

// Match 执行匹配
func (m *ExpressionMatcher) Match(response *Response, variables map[string]string) bool {
	expr := m.expression
	
	// 替换变量
	for key, value := range variables {
		expr = strings.ReplaceAll(expr, "{{"+key+"}}", value)
	}

	// 解析表达式
	conditions := strings.Split(expr, "&&")
	
	for _, condition := range conditions {
		condition = strings.TrimSpace(condition)
		if !m.evaluateCondition(condition, response) {
			return false
		}
	}
	
	return true
}

// evaluateCondition 评估单个条件
func (m *ExpressionMatcher) evaluateCondition(condition string, response *Response) bool {
	// 状态码匹配: status == 200
	if strings.Contains(condition, "status") {
		return m.matchStatus(condition, response.StatusCode)
	}
	
	// 响应体匹配: body contains "text"
	if strings.Contains(condition, "body") {
		return m.matchBody(condition, response.Body)
	}
	
	// 响应头匹配: header["Content-Type"] contains "json"
	if strings.Contains(condition, "header") {
		return m.matchHeader(condition, response.Headers)
	}
	
	// 响应时间匹配: time < 1000
	if strings.Contains(condition, "time") {
		return m.matchTime(condition, response.Time)
	}
	
	return false
}

// matchStatus 匹配状态码
func (m *ExpressionMatcher) matchStatus(condition string, statusCode int) bool {
	if strings.Contains(condition, "==") {
		parts := strings.Split(condition, "==")
		if len(parts) == 2 {
			expected, _ := strconv.Atoi(strings.TrimSpace(parts[1]))
			return statusCode == expected
		}
	}
	
	if strings.Contains(condition, "!=") {
		parts := strings.Split(condition, "!=")
		if len(parts) == 2 {
			expected, _ := strconv.Atoi(strings.TrimSpace(parts[1]))
			return statusCode != expected
		}
	}
	
	return false
}

// matchBody 匹配响应体
func (m *ExpressionMatcher) matchBody(condition string, body string) bool {
	if strings.Contains(condition, "contains") {
		parts := strings.Split(condition, "contains")
		if len(parts) == 2 {
			needle := strings.Trim(strings.TrimSpace(parts[1]), "\"'")
			return strings.Contains(body, needle)
		}
	}
	
	if strings.Contains(condition, "matches") {
		parts := strings.Split(condition, "matches")
		if len(parts) == 2 {
			pattern := strings.Trim(strings.TrimSpace(parts[1]), "\"'")
			re, err := regexp.Compile(pattern)
			if err != nil {
				return false
			}
			return re.MatchString(body)
		}
	}
	
	if strings.Contains(condition, "startswith") {
		parts := strings.Split(condition, "startswith")
		if len(parts) == 2 {
			prefix := strings.Trim(strings.TrimSpace(parts[1]), "\"'")
			return strings.HasPrefix(body, prefix)
		}
	}
	
	return false
}

// matchHeader 匹配响应头
func (m *ExpressionMatcher) matchHeader(condition string, headers map[string][]string) bool {
	// 提取头部名称
	start := strings.Index(condition, "[")
	end := strings.Index(condition, "]")
	
	if start == -1 || end == -1 {
		return false
	}
	
	headerName := strings.Trim(condition[start+1:end], "\"'")
	headerValues, exists := headers[headerName]
	
	if !exists {
		return false
	}
	
	headerValue := strings.Join(headerValues, " ")
	
	if strings.Contains(condition, "contains") {
		parts := strings.Split(condition[end+1:], "contains")
		if len(parts) == 2 {
			needle := strings.Trim(strings.TrimSpace(parts[1]), "\"'")
			return strings.Contains(headerValue, needle)
		}
	}
	
	return false
}

// matchTime 匹配响应时间
func (m *ExpressionMatcher) matchTime(condition string, time int64) bool {
	if strings.Contains(condition, "<") {
		parts := strings.Split(condition, "<")
		if len(parts) == 2 {
			threshold, _ := strconv.ParseInt(strings.TrimSpace(parts[1]), 10, 64)
			return time < threshold
		}
	}
	
	if strings.Contains(condition, ">") {
		parts := strings.Split(condition, ">")
		if len(parts) == 2 {
			threshold, _ := strconv.ParseInt(strings.TrimSpace(parts[1]), 10, 64)
			return time > threshold
		}
	}
	
	return false
}